//公共模块
import regeneratorRuntime from '../libs/runtime.js';
const util = require('../utils/util.js');

class $ {
  constructor() {
    this.version = '1.00.00'
    this.appid = 'wx37db259f06364750'
    this.requestUrl = () => wx.getStorageSync('$requestUrl') || "https://www.zjkeday.cn"
    this.self = () => (getCurrentPages()[getCurrentPages().length - 1] || {
      setData: () => {}
    })
    this.parent = (num = 1) => (getCurrentPages()[getCurrentPages().length - (num + 1)] || {})
    this.data = data => data.currentTarget.dataset
    this.gData = () => getApp().globalData
    this.token = () => wx.getStorageSync('token') || ""
    this.uuid = () => wx.getStorageSync('uuid') || ""
    this.logged = () => (this.token() && this.uuid()) ? true : false
    this.isTeacher = (update) => {
      if (!update) {
        this.getPower()
      }
      return (wx.getStorageSync('$isTeacher') == 'yes') ? true : false
    }
    this.noImage = "https://kdimgs.oss-cn-hangzhou.aliyuncs.com/sxzlogo/avatar.png"
    this.device = wx.getSystemInfoSync()
  }

  PageIdx(idx, limit = 10) {
    let page = parseInt(idx / limit) + 1;
    return {
      page,
      index: idx - (page - 1) * limit,
    }
  }

  width_equal(grid, fix) {
    let width = this.device.windowWidth;
    return (width - fix) / grid;
  }

  msg(title) {
    wx.showToast({
      title,
    })
  }

  //Setting
  setting(auth, callback) {
    wx.getSetting({
      success: (res) => {
        let authSetting = res.authSetting || {}
        let msg = "抱歉，此功能需要您授权相关权限！"
        if (auth == "scope.userLocation") {
          msg = "抱歉，此功能需要您在设置里允许[使用我的地理位置]！"
        }
        if (auth == "scope.writePhotosAlbum") {
          msg = "抱歉，此功能需要您在设置里允许[保存到相册]！"
        }
        if (auth == "scope.record") {
          msg = "抱歉，此功能需要您在设置里允许[麦克风]！"
        }
        if (authSetting[auth] === false) {
          this.alert(msg, () => {
            this.navigateTo("/setting/list")
          })
        } else {
          callback && callback()
        }
      }
    })
  }
  //assign
  assign(...arg) {
    for (let i = 1; i < arg.length; i++) {
      for (let n in arg[i]) {
        arg[0][n] = arg[i][n]
        //arg[i][n] && [arg[0][n] = arg[i][n]]
      }
    }
  }

  objIndexOf(arr, val, key = "") {
    let status = -1
    for (let i = 0; i < arr.length; i++) {
      let _arrstr = ""
      let _valstr = ""
      if (typeof val == 'object') {
        _arrstr = arr[i][key] || arr[i].id || arr[i].uuid || arr[i]._id
        _valstr = val[key] || val.id || val.uuid || val._id
      }
      if (arr[i] == val || (_arrstr && (_arrstr == _valstr))) {
        status = 0
        break;
      }
    }
    return status
  }

  //arrayRm
  arrayRm(arr, val, cb, key = "") {
    for (let i = 0; i < arr.length; i++) {
      let _arrstr = ""
      let _valstr = ""
      if (typeof val == 'object') {
        _arrstr = arr[i][key] || arr[i].uuid || arr[i]._id || arr[i].id
        _valstr = val[key] || val.uuid || val._id || val.id
      }
      if (arr[i] == val || (_arrstr && (_arrstr == _valstr))) {
        arr.splice(i, 1);
        cb && cb();
        break;
      }
    }
  }

  //array delete
  setDelete(array, index) {
    let set = new Set(array)
    set.delete(array[index])
    return Array.from(set)
  }

  selfData() {
    return this.self().data || {}
  }

  parentData(num = 1) {
    let pages = getCurrentPages()
    let lg = pages.length - (num + 1)
    let data = (lg > -1) ? pages[lg].data : {}
    return data
  }

  formData(data) {
    let obj = {}
    for (let i in data) {
      if (i.indexOf("_cbData") == -1 && i.indexOf("_callback") == -1) {
        obj[i] = data[i]
      }
    }
    return obj
  }

  //route
  curPage(route) {
    let curPage = {}
    let pages = getCurrentPages()
    for (let i in pages) {
      if (pages[i].route == ("pages" + route)) {
        curPage = pages[i]
        break
      }
    }
    return curPage
  }

  //hasCurPage
  hasCurPage(route) {
    return !this.isEmptyObject(this.curPage(route))
  }

  //Short
  short(obj, childs, length = 8) {
    for (let s = 0; s < childs.length; s++) {
      let son = childs[s]
      let child = obj[son] || ''
      if (child.length > length) {
        obj[son + 'Short'] = child.substr(0, length) + "..."
      } else {
        child && [obj[son + 'Short'] = child]
      }
    }
  }

  //isEmptyObject
  isEmptyObject(e) {
    for (let t in e)
      return !1
    return !0
  }

  hasEmptyObject(e) {
    let status = false
    for (let t in e) {
      (this.hasBlankSpace(e[t])) && [status = true]
    }
    return status
  }

  //isBlankSpace
  isBlankSpace(str) {
    if (typeof str == "string") {
      while (str.lastIndexOf(" ") >= 0) {
        str = str.replace(" ", "")
      }
      return (str.length == 0) ? true : false
    } else {
      return false
    }
  }

  //hasBlankSpace
  hasBlankSpace(str) {
    return this.isBlankSpace(str)
  }

  // 字符串转浮点数
  safeStrToFloat(obj) {
    if (!obj) return 0
    if (isNaN(obj)) return 0
    return parseFloat(obj)
  }
  // 字符串转整数数
  safeStrToInt(obj) {
    if (!obj) return 0
    if (isNaN(obj)) return 0
    return parseInt(obj)
  }
  // 时间格式化
  timeFormat(fmt, date) {
    var o = {
      "M+": date.getMonth() + 1, //月份   
      "d+": date.getDate(), //日
      "h+": date.getHours(), //小时   
      "m+": date.getMinutes(), //分   
      "s+": date.getSeconds(), //秒   
      "q+": Math.floor((date.getMonth() + 3) / 3), //季度   
      "S": date.getMilliseconds() //毫秒   
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
      if (new RegExp("(" + k + ")").test(fmt))
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
  }

  /**
   * 日期格式化
   */
  dateFormat(fmt, date) {
    let ret;
    const opt = {
      "Y+": date.getFullYear().toString(), // 年
      "m+": (date.getMonth() + 1).toString(), // 月
      "d+": date.getDate().toString(), // 日
      "H+": date.getHours().toString(), // 时
      "M+": date.getMinutes().toString(), // 分
      "S+": date.getSeconds().toString() // 秒
      // 有其他格式化字符需求可以继续添加，必须转化成字符串
    };
    for (let k in opt) {
      ret = new RegExp("(" + k + ")").exec(fmt);
      if (ret) {
        fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
      };
    };
    return fmt;
  }
  //往前后改变天数
  changeDay(i) {
    if (!this.currentFirstDate) {
      this.currentFirstDate = new Date();
    }
    let formatDate = date => {
      let year = date.getFullYear() + "-";
      let month = date.getMonth() + 1 + "-";
      let day = date.getDate();
      return year + month + day;
    };
    let addDate = (date, n) => {
      date.setDate(date.getDate() + n);
      return date;
    };
    let setDate = date => {
      let week = date.getDay() - 1;
      date = addDate(date, week * -1);
      this.currentFirstDate = new Date(date);
      return formatDate(date);
    };
    return setDate(addDate(this.currentFirstDate, i));
  }
  // 时间格式转换
  getTimer(stringTime) {
    var minute = 1000 * 60;
    var hour = minute * 60;
    var day = hour * 24;
    var week = day * 7;
    var month = day * 30;
    var time1 = new Date().getTime(); //当前的时间戳
    stringTime = stringTime.replace(/-/g, "/")

    var time2 = Date.parse(new Date(stringTime)); //指定时间的时间戳
    var time = time1 - time2;
    var result = null;
    if (time < 0) {
      result = "早于当前时间";
    } else if (time / month >= 1) {
      // result = parseInt(time/month) + "月前";
      result = stringTime.split(" ")[0].replace(/\//g, '.')
    } else if (time / week >= 1) {
      // result =parseInt(time/week) + "周前";
      result = stringTime.split(" ")[0].replace(/\//g, '.')
    } else if (time / day >= 1) {
      if (parseInt(time / day) > 1) {
        result = stringTime.split(" ")[0].replace(/\//g, '.')
      } else {
        result = parseInt(time / day) + "天前";
      }
    } else if (time / hour >= 1) {
      result = parseInt(time / hour) + "小时前";
    } else if (time / minute >= 5) {
      result = parseInt(time / minute) + "分钟前";
    } else {
      result = "刚刚";
    }
    return result
  }

  //getMD
  getMD(m = 0, d = 0) {
    let date = new Date()
    let _fn = (str) => ((str).toString().length == 1) ? "0" + str : str
    return _fn(date.getMonth() + m + 1) + "-" + _fn(date.getDate() + d)
  }

  //getYMD
  //当前d加减天方法只支持前后跨度一个月，调月份使用参数m,调年份使用参数y
  getYMD(y = 0, m = 0, d = 0) {
    if (y === 0 && m === 0) {
      return util.Fungetdate(d).join('-')
    }
    let _d = d;
    if (_d > 28 || _d < -28) {
      console.error("$.getYMD()方法天数范围暂时只支持-28 至 +28，如需跨月或年，请使用y或m参数")
      return;
    }
    let MD = {
      1: 31,
      2: 28,
      3: 31,
      4: 30,
      5: 31,
      6: 30,
      7: 31,
      8: 31,
      9: 30,
      10: 31,
      11: 30,
      12: 31
    }
    let date = new Date()
    let _fn = (str) => ((str).toString().length == 1) ? "0" + str : str

    //每月开头(减天数)
    if (date.getDate() <= -(_d) && _d < 0) {
      m -= 1
      d += MD[date.getMonth()]
    }
    //每月结尾(加天数)
    if (MD[date.getMonth() + 1] <= (date.getDate() + _d) && _d > 0) {
      m += 1
      d -= MD[date.getMonth() + 1]
    }

    let _y = date.getFullYear() + y
    let _m = date.getMonth() + m + 1
    if (_m === 13) {
      _m = 1
      _y += 1
    }
    return _fn(_y) + "-" + _fn(_m) + "-" + _fn(date.getDate() + d)
  }

  //getYMD
  getHMS(h = 0, m = 0, s = 0) {
    let date = new Date()
    let _fn = (str) => ((str).toString().length == 1) ? "0" + str : str
    return _fn(date.getHours() + h) + ":" + _fn(date.getMinutes() + m) + ":" + _fn(date.getSeconds() + s)
  }

  //getFullTime
  getFullTime(timestamp = false, time = (this.getYMD() + " " + this.getHMS())) {
    if (timestamp) {
      time = parseInt(time.split(" ")[0].split("-").join("") + time.split(" ")[1].split(":").join(""))
    }
    return time
  }

  getFormatHM(time) {
    if (!time) {
      return "";
    }
    let hms = time.split(" ")[1].split(":");
    return hms[0] + ":" + hms[1];
  }

  //guid
  guid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
      let r = Math.random() * 16 | 0,
        v = c == 'x' ? r : (r & 0x3 | 0x8)
      return v.toString(16)
    })
  }

  //timeDelay
  timeDelay(h, length, type) {
    let hour = h.split(':')[0]
    let min = h.split(':')[1]
    let start_length = Number(hour * 3600) + Number(min * 60)
    let m = Number(length * 60)
    let HH = ''
    let mm = ''
    if (type !== 2) {
      HH = parseInt((start_length + m) / 3600)
      mm = (start_length + m) % 3600 / 60
      if (HH < 10) {
        HH = "0" + "" + HH
      }
      if (mm < 10) {
        mm = "0" + "" + mm
      }
      return HH + ":" + mm
    } else {
      HH = parseInt((start_length - m) / 3600)
      mm = (start_length - m) % 3600 / 60
      if (HH < 10) {
        HH = "0" + "" + HH
      }
      if (mm < 10) {
        mm = "0" + "" + mm
      }
      return HH + ":" + mm
    }
  }

  //testTel
  testTel(tel) {
    let telRule = /^1[2|3|4|5|6|7|8|9]\d{9}$/
    return telRule.test(tel)
  }
  //get请求
  get(url, data = {}, callback, error, loading = true, login = true) {
    if (!url) {
      return false
    }
    wx.showNavigationBarLoading()
    this.selfData().$loading = true
    this.self().setData({
      $loading: true
    })
    if(!data.token){
      data.token = this.token()
    }
    data.apply = 'USER_SIDE'
    data.version = 'I-2.2.7'
    if (typeof data.client == "undefined") {
      data.client = "wxxcx";
    }
    if (typeof data.campus_uuid == "undefined" && wx.getStorageSync('cmp_uuid')) {
      data.campus_uuid = wx.getStorageSync('cmp_uuid')
    }
    url = url.replace("http://", "https://")
    return wx.request({
      url: (url.indexOf("://") > -1) ? url : this.requestUrl() + url,
      data,
      header: {
        'content-type': 'application/json'
      },
      success: (e) => {
        this.selfData().$loading = false
        this.self().setData({
          $loading: false
        })
        wx.hideNavigationBarLoading()
        wx.stopPullDownRefresh()
        let res = e.data
        if (res && res.status == "success") {
          callback && callback(res.data, res.message)
        } else {
          error && error(res, e.statusCode);
          if (!error) {
            if (!res.status) {
              this.tip("网络异常，请稍后重新操作！")
            } else {
              (typeof res == "string") ? this.tip(res): this.tip(res.message || "API请求异常!")
            }
          }
          if (login && res && res.action == "login") {
            if (!wx.getStorageSync('firstRun')) {
              this.login()
              wx.setStorageSync('firstRun', "no")
            } else {
              if (!wx.getStorageSync('$alreadyLoginWindow')) {
                wx.setStorageSync('$alreadyLoginWindow', 'yes')
                //this.alert("您未登录或登录已过期,请重新登录！", () => {
                wx.removeStorageSync('token')
                wx.removeStorageSync('uuid')
                wx.removeStorageSync('cmp_uuid')
                this.login()
                //})
              }
            }
          }
        }
      },
      fail: (e) => {
        error && error(e, e.statusCode);
        this.selfData().$loading = false
        this.self().setData({
          $loading: false
        })
        wx.hideNavigationBarLoading()
        wx.stopPullDownRefresh()
        if (!error) {
          this.tip(e && e.errMsg)
        }
        console.log(e)
      }
    })
  }

  loading(time) {
    wx.showToast({
      title: 'loading...',
      icon: 'loading',
      mask: true,
      duration: time || 6000
    })
  }

  //post
  post(url, data = {}, callback, error, loading = true) {
    if (!url) {
      return false
    }
    if (loading) {
      this.loading();
    }
    if(!data.token){
      data.token = this.token()
    }
    data.apply = 'USER_SIDE'
    data.version = 'I-2.2.7'
    if (typeof data.client == "undefined") {
      data.client = "wxxcx";
    }
    if (typeof data.campus_uuid == "undefined" && wx.getStorageSync('cmp_uuid')) {
      data.campus_uuid = wx.getStorageSync('cmp_uuid')
    }
    url = url.replace("http://", "https://")
    return wx.request({
      url: (url.indexOf("://") > -1) ? url : this.requestUrl() + url,
      method: "POST",
      data,
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      success: (e) => {
        wx.hideToast()
        let res = e.data
        if (res && res.status == "success") {
          callback && callback(res.data, res.message)
        } else {
          error && error(res, e);
          if (!error) {
            if (!res.status) {
              this.tip("网络异常，请稍后重新操作！")
            } else {
              (typeof res == "string") ? this.tip(res): this.tip(res.message || "API请求异常!")
            }
          }
          if (res && res.action == "login") {
            //this.alert("您未登录或登录已过期,请重新登录！", () => {
            wx.removeStorageSync('token')
            wx.removeStorageSync('uuid')
            wx.removeStorageSync('cmp_uuid')
            this.login()
            //})
          }
          console.log(res)
        }
      },
      fail: (e) => {
        wx.hideToast()
        this.tip(e && e.errMsg)
        console.log(e)
      }
    })
  }

  //webview
  webview(opt, type) {
    if (opt.url.indexOf("order") > -1) {
      wx.login({
        success: (res) => {
          this.navigateTo("/_common/webview?url=" + encodeURIComponent(opt.url) + "&title=" + opt.title + "&code=" + res.code, type)
        }
      })
    } else {
      this.navigateTo("/_common/webview?url=" + encodeURIComponent(opt.url) + "&title=" + opt.title, type)
    }
  }

  //xcx
  xcx(opt) {
    let appId = ""
    if (opt.type == "qxdt") {
      appId = 'wx218db550bf66dc38'
    } else if (opt.type == "dt") {
      appId = 'wx512a1c73bf234c3f'
    } else if (opt.type === "manke") {
      appId = "wxc219e0efae9c9e82"
    }
    console.log(opt.path + '?u_token=' + this.token() + '&u_uuid=' + this.uuid() + '&u_cmp_uuid=' + wx.getStorageSync('cmp_uuid') + this.urlEncode(opt.data || {}))
    wx.navigateToMiniProgram({
      appId,
      path: opt.path + '?u_token=' + this.token() + '&u_uuid=' + this.uuid() + '&u_cmp_uuid=' + wx.getStorageSync('cmp_uuid') + this.urlEncode(opt.data || {}),
      envVersion: opt.envVersion || 'develop'
    })
  }

  // 多图上传 
  async uploadFileList(url, data = {}, callback, error) {
    let fileList = data.fileList
    let prefix = data.prefix
    let imgurls = []
    for (let i in fileList) {
      wx.showToast({
        title: `正在上传第${parseInt(i) + 1}张图片`,
        icon: 'loading',
        mask: true,
        duration: 10000
      })
      await new Promise((res, rej) => {
        this.upload(
          url, {
            filePaths: fileList[i],
            prefix,
            fileSize: 10,
          },
          (data) => {
            imgurls.push(data[0])
            res()
          },
          (err) => {
            error(err)
            return
          },
          false
        )
      })
    }
    await callback(imgurls)
  }

  //upload
  upload(url, data = {}, callback, error, loading = true) {
    if (loading) {
      wx.showToast({
        title: 'loading...',
        icon: 'loading',
        mask: true,
        duration: 6000
      })
    }
    data.token = this.token()
    data.client = "wxxcx"
    let filePath = (typeof data.filePaths == 'string') ? data.filePaths : data.filePaths[0]
    let fileSize = data.fileSize || 2
    wx.getFileInfo({
      filePath: filePath,
      success: (file) => {
        let $fileSize = (file.size / 1024 / 1024).toFixed(2)
        if ($fileSize > fileSize) {
          wx.hideToast()
          this.alert("抱歉,文件过大,当前文件为" + $fileSize + "MB,暂时只支持最大" + fileSize + "MB文件上传！")
        } else {
          let _fun = (param) => {
            let uploadTask = wx.uploadFile({
              url: param.url,
              header: {
                'content-type': 'multipart/form-data'
              },
              filePath: filePath,
              name: data.ossDirect ? 'file' : data.filename ? data.filename : 'filename',
              formData: param.data,
              success: (e) => {
                wx.hideToast()
                if (data.ossDirect) {
                  e.statusCode == 200
                  e.data = `{"status": "success", "data": ["${data.prefix}${param.data.name}"]}`
                }
                if (e && e.statusCode == 200) {
                  let res = JSON.parse(e.data)
                  if (res.status == "success") {
                    if (data.ossDirect) {
                      if (data.ossDirect == 'audio') {
                        callback && callback(res.data, res)
                      } else {
                        this.get("/oss/video/transcoding", {
                          video_path: `${data.prefix}${param.data.name}`,
                          duration: data.fileTime || 30
                        }, (trd) => {
                          callback && callback(res.data, trd.video_url, trd)
                        })
                      }
                    } else {
                      callback && callback(res.data)
                    }
                  } else {
                    if (error) {
                      error(res);
                    } else {
                      (typeof res == "string") ? this.tip(res): this.tip(res.message || "API请求异常!")
                    }
                    if (res && res.message == "该用户不存在！") {
                      this.login()
                    }
                    console.log(res)
                  }
                } else {
                  error ? error(e) : this.tip(e.errMsg);
                }
              },
              fail: (e) => {
                wx.hideToast()
                this.tip("您的网络环境不稳定，请切换重试")
                console.log(e)
              }
            })
            uploadTask.onProgressUpdate((res) => {
              data.uploadTask && data.uploadTask(res)
            })
          }
          if (data.ossDirect) {
            this.get("/oss/token", {
              file_type: data.ossDirect
            }, (param) => {
              let name = this.guid() + (data.ossDirect == 'audio' ? '.mp3' : '.mp4')
              _fun({
                url: param.token.host,
                data: {
                  name: name,
                  key: data.prefix + name,
                  policy: param.token.policy,
                  OSSAccessKeyId: "LTAIHIRCMtnNxQ06",
                  success_action_status: "200",
                  signature: param.token.signature
                }
              })
            })
          } else {
            _fun({
              url: this.requestUrl() + url,
              data: data
            })
          }
        }
      },
      fail: (e) => {
        this.tip(e.errMsg)
        console.log(e)
      }
    })
  }

  urlEncode(param, key, encode) {
    if (param == null) return '';
    let paramStr = '';
    let t = typeof (param);
    if (t == 'string' || t == 'number' || t == 'boolean') {
      paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param);
    } else {
      for (let i in param) {
        let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
        paramStr += this.urlEncode(param[i], k, encode);
      }
    }
    return paramStr;
  }

  //download
  download(url, data = {}, callback) {
    if (!url) {
      return false
    }
    data.token = this.token()
    data.client = "wxxcx";
    if (!data.campus_uuid && wx.getStorageSync('cmp_uuid')) {
      data.campus_uuid = wx.getStorageSync('cmp_uuid')
    }
    //url = url.replace("http://", "https://")
    return wx.downloadFile({
      url: url + "?" + this.urlEncode(data),
      success: (res) => {
        callback && callback(res)
      }
    })
  }

  //login
  login() {
    if (!this.logged() && !this.hasCurPage("/login/index")) {
      console.log("即将打开登录窗口...")
      wx.reLaunch({
        url: '/pages/login/index'
      })
    }
  }

  //login_open
  login_open(cb) {
    if (!this.logged() && !this.hasCurPage("/login/index")) {
      this.navigateTo("/login/index?type=open")
    } else {
      cb && cb()
    }
  }

  //cmp_uuid
  cmp_uuid(callback, show = true) {
    let cmp_uuid = wx.getStorageSync('cmp_uuid') || ""
    if (cmp_uuid) {
      callback && callback(cmp_uuid)
      return cmp_uuid
    } else {
      this.get("/user/ins", {}, (e) => {
        let ins = e.institutions || []
        this.gData().insList = ins
        if (ins.length > 0) {
          // 默认取第一个学校
          let ins_uuid = ins[0].institution_uuid
          ins.map((i) => {
            if (i.last_institution && i.last_institution == 'YES') {
              // 最后操作的学校
              ins_uuid = i.institution_uuid
            }
          })
          this.gData().ins_uuid = ins_uuid
          let campus_uuid = ''
          this.get("/user/ins/campus", {
            institution_uuid: ins_uuid
          }, (e) => {

            let campus = e.campuss || []
            campus_uuid = campus[0].campus_uuid
            campus.map((i) => {
              if (i.last_campus && i.last_campus == 'YES') {
                // 最后操作的校区
                campus_uuid = i.campus_uuid
                this.gData().campusData = i
              }
            })
            wx.setStorageSync('cmp_uuid', campus_uuid)
            callback && callback(campus_uuid)
          }, () => {}, false, show)
          this.updatePower(campus_uuid)
          return campus_uuid
        } else {
          // 没有学校--->创建学校
          show && (this.navigateTo("/institution/choose"))
        }
      }, () => {}, false, show)
    }
  }

  //navigateTo
  navigateTo(url, type) {
    if (type == 1) {
      wx.redirectTo({
        url: '/pages' + url
      })
    } else if (type == 2) {
      wx.reLaunch({
        url: '/pages' + url
      })
    } else {
      if (url.indexOf('packageA') > -1) {
        wx.navigateTo({
          url: url
        })
      } else {
        wx.navigateTo({
          url: '/pages' + url
        })
      }
    }
  }

  navigateBack(time = 0) {
    setTimeout(() => {
      wx.navigateBack()
    }, time)
  }

  //richText
  richText(richText, cb) {
    if (richText && richText.length > 0) {
      this.selfData()._$richText = richText
      wx.navigateTo({
        url: '/packageA/richText/content'
      })
    } else {
      cb && cb()
    }
  }

  //editText
  editText(key, value, option = {}) {
    let module = this.selfData()["$ET_data"];
    !module && [this.selfData().$ET_data = {}]
    if (key && typeof value == "undefined" && !option.title) {
      return this.selfData()["$ET_data"][key] || ""
    }
    if (key && option.title) {
      let param = option.param || {}
      let before = option.before || ""
      delete this.selfData()["$ET_data"]["before"]
      if (before) {
        this.selfData()["$ET_data"]["before"] = before
      }
      let et = {}
      et.key = key || "";
      et.value = value || "";
      et.api = option.api || "";
      et.type = option.type || "";
      et.mold = option.mold || "";
      et.maxlength = option.maxlength || "";
      et.title = option.title || "";
      et.desc = option.desc || "";
      et.required = option.required || "";
      et.param = encodeURI(JSON.stringify(param));
      this.selfData()._$editText = et
      this.navigateTo("/_common/editText")
    }
    if (!key && !value) {
      return this.selfData()["$ET_data"] || {}
    }
  }

  //editTextAssign
  editTextAssign(obj) {
    this.assign(obj, this.editText())
  }

  //checkbox
  checkbox(data = [], checkedId = "uuid") {
    if (Array.isArray(data) && data.length > 0) {
      let checkedlist = this.selfData()['checkedlist'] || []
      this.selfData().checkboxItems = data.map((v, k) => {
        let selfChecked = this.selfData()[checkedId] || []
        if (selfChecked.length > 0 && selfChecked.indexOf(v[checkedId]) > -1) {
          v.checked = true;
          if (this.objIndexOf(checkedlist, v, checkedId) == -1) {
            //this.selfData()[checkedId].push(v[checkedId])
            checkedlist.push(v)
          }
        } else {
          v.checked = false
        }
        v.value = k
        return v
      })
      this.self().setData({
        checkboxItems: this.selfData().checkboxItems,
        checkedlist: checkedlist
      })
    } else {
      let res = []
      this.selfData().checkboxItems.map((v, k) => {
        v.checked && [(data == "$all") ? res.push(v) : res.push(v[data])]
      })
      return res
    }
  }

  //checkboxTap
  checkboxTap(e, checkedId = "uuid") {
    this.self().setData({
      checkboxClick: this.data(e).item[checkedId]
    })
  }

  //checkboxChangeInit
  checkboxChangeInit() {
    setTimeout(() => {
      this.checkboxChange(...arguments);
    }, 100)
  }

  //checkboxChange
  checkboxChange(e, type = 0, checkedId = "uuid") {
    //values: [0,1,2...] 索引
    let [checkboxItems, values] = [this.selfData().checkboxItems, e.detail.value]
    if (type) {
      //type: 1 单选， type: 0 多选
      this.selfData()[checkedId] = []
      this.selfData().checkedlist = []
    }
    this.selfData()[checkedId] = this.selfData()[checkedId] || []
    let checkedlist = this.selfData().checkedlist || []
    checkedlist.map((v) => {
      if (v[checkedId] == this.selfData().checkboxClick) {
        this.arrayRm(this.selfData()[checkedId], v[checkedId], "", checkedId)
        this.arrayRm(checkedlist, v, "", checkedId)
      }
    })

    for (let i = 0, lenI = checkboxItems.length; i < lenI; ++i) {
      checkboxItems[i].checked = false
      for (let j = 0, lenJ = values.length; j < lenJ; ++j) {
        if (checkboxItems[i].value == values[lenJ - 1] && type) {
          checkboxItems[i].checked = true
          this.selfData()[checkedId].push(checkboxItems[i][checkedId])
          if (this.objIndexOf(checkedlist, checkboxItems[i], checkedId) == -1) {
            checkedlist.push(checkboxItems[i])
          }
          break
        }
        if (checkboxItems[i].value == values[j] && !type) {
          checkboxItems[i].checked = true
          if (this.objIndexOf(checkedlist, checkboxItems[i], checkedId) == -1) {
            this.selfData()[checkedId].push(checkboxItems[i][checkedId])
            checkedlist.push(checkboxItems[i])
          }
          break
        }
      }
    }
    if (values.length === 0) {
      this.self().setData({
        checkboxItems: checkboxItems,
        checkedlist: [],
        [checkedId]: [],
      })
    } else {
      this.self().setData({
        checkboxItems: checkboxItems,
        checkedlist: checkedlist,
        [checkedId]: this.selfData()[checkedId],
      })
    }
  }

  //checkboxSet
  checkboxSet(obj, status = false, checkedId = 'uuid') {
    let checkedlist = this.selfData()['checkedlist'] || []
    this.selfData().checkboxItems = this.selfData().checkboxItems.map((v) => {
      if (v[checkedId] == obj[checkedId]) {
        v.checked = status
      }
      return v
    })
    if (status && this.objIndexOf(checkedlist, obj, checkedId) == -1) {
      this.selfData()[checkedId].push(obj[checkedId])
      checkedlist.push(obj)
    }
    if (!status) {
      let $checked = this.selfData()[checkedId]
      this.arrayRm($checked, obj[checkedId], "", checkedId)
      this.arrayRm(checkedlist, obj, "", checkedId)
    }
    this.self().setData({
      checkboxItems: this.selfData().checkboxItems,
      checkedlist: checkedlist
    })
  }

  //checkboxCheckAll
  //checkedId 命名为uuid 存在隐患
  checkboxCheckAll(status = true, checkedId = 'uuid') {
    let checkboxItems = this.selfData().checkboxItems
    let checkedIds = [];
    for (let i = 0, lenI = checkboxItems.length; i < lenI; ++i) {
      // checkboxItems[i].checked = status
      // checkedIds.push(checkboxItems[i][checkedId])
      checkedIds.push(i);
    }
    // this.self().setData({
    //   checkboxItems: checkboxItems,
    //   checkedlist: status? checkboxItems: [],
    //   [checkedId]: status? checkedIds: [],
    // })

    this.checkboxChange({
      detail: {
        value: status ? checkedIds : [],
      }
    }, 0, checkedId)

    return status
  }

  //checkboxCheckRev
  checkboxCheckRev() {
    let checkboxItems = this.selfData().checkboxItems
    for (let i = 0, lenI = checkboxItems.length; i < lenI; ++i) {
      (checkboxItems[i].checked) ? [checkboxItems[i].checked = false] : [checkboxItems[i].checked = true]
    }
    this.self().setData({
      checkboxItems: checkboxItems
    })
  }

  //radio
  radio(data = [], checkedId) {
    if (Array.isArray(data) && data.length > 0) {
      this.selfData().radioItems = data.map((v, k) => {
        let selfRadio = this.selfData()["radioChecked"][checkedId] || []
        if (selfRadio.length > 0 && selfRadio.indexOf(v[checkedId]) > -1) {
          v.checked = true
        } else {
          v.checked = false
        }
        v.value = k
        return v
      })
      this.self().setData({
        radioItems: this.selfData().radioItems
      })
    } else {
      let res = []
      this.selfData().radioItems.map((v, k) => {
        v.checked && [(data == "$all") ? res.push(v) : res.push(v[data])]
      })
      return res
    }
  }

  //radioChange
  radioChange(e) {
    let radioItems = this.selfData().radioItems;
    for (let i = 0, len = radioItems.length; i < len; ++i) {
      radioItems[i].checked = radioItems[i].value == e.detail.value;
    }
    this.self().setData({
      radioItems: radioItems
    })
  }

  //Tips
  tip($tipContent) {
    let This = this.self()
    if (typeof $tipContent == "boolean") {
      This.setData({
        $showTip: $tipContent
      })
    } else {
      clearTimeout(this._STtip)
      This.setData({
        $showTip: true,
        $tipContent: $tipContent || ""
      })
      this._STtip = setTimeout(() => {
        This.setData({
          $showTip: false
        })
      }, 3000)
    }
  }

  range(opt) {
    let This = this.self()
    let {
      title,
      value = ['', ''],
      type = 'num',
      success
    } = opt
    This.data.$range = {
      title,
      value,
      type,
      status: true
    }
    This.$rangeValue_0 = (e) => {
      This.data.$range.value[0] = e.detail.value
    }
    This.$rangeValue_1 = (e) => {
      This.data.$range.value[1] = e.detail.value
    }
    This.$rangeClose = () => {
      This.data.$range.status = false
      This.setData({
        $range: This.data.$range
      })
    }
    This.$rangeSure = () => {
      This.$rangeClose()
      let val = This.data.$range.value
      success && success(This.data.$range.value)
    }
    This.setData({
      $range: This.data.$range
    })
  }

  prompt($promptText, $promptVal = "", callback, $maxlength = "", $textarea = "", opt = {}) {
    let This = this.self()
    This.data.$prompt = {
      $promptText,
      $promptVal,
      value: "",
      $textarea,
      $maxlength,
      num: $promptVal.length,
      $type: opt.type || "text",
      status: false,
      changeStatus: false
    }
    This.$promptValue = (e) => {
      This.setData({
        ['$prompt.num']: e.detail.cursor
      })

      This.data.$prompt.value = e.detail.value
      This.data.$prompt.changeStatus = true
    }
    This.$promptClose = () => {
      This.data.$prompt.status = false
      This.setData({
        $prompt: This.data.$prompt
      })
      opt.end && opt.end()
    }
    This.$promptSure = () => {
      This.$promptClose()
      let val = This.data.$prompt.value
      if (This.data.$prompt.changeStatus && !val) {
        callback && callback("")
      } else {
        let values
        if ($maxlength) {
          values = (val.length > $maxlength ? val.substring(0, $maxlength) : val) || ($promptVal.length > $maxlength ? $promptVal.substring(0, $maxlength) : $promptVal)
        } else {
          values = val || $promptVal
        }
        callback && callback(values)
      }
    }
    This.data.$prompt.status = true
    This.setData({
      $prompt: This.data.$prompt
    })
  }

  $prompt(opt, callback) {
    this.prompt(opt.title, opt.value, callback, opt.maxlength, opt.textarea, opt)
  }

  prompts(list = [], callback) {
    let This = this.self()
    This.data.$prompts = {
      list,
      status: false
    }
    list.map((v, k) => {
      This["$promptsValue_" + k] = (e) => {
        This.data.$prompts.list[k].value = e.detail.value.replace(/\s/g, "")
      }
    })
    This.$promptsClose = () => {
      This.data.$prompts.status = false
      This.setData({
        $prompts: This.data.$prompts
      })
    }
    This.$promptsSure = () => {
      This.$promptsClose()
      callback && callback(This.data.$prompts.list)
    }
    This.data.$prompts.status = true
    This.setData({
      $prompts: This.data.$prompts
    })
  }

  //alert
  alert(content, success) {
    wx.showModal({
      content: content.toString(),
      showCancel: false,
      success: function (res) {
        if (res.confirm) {
          success && success()
        }
      }
    });
  }

  //confirm
  confirm(content, sure, opt = {}) {
    wx.showModal({
      content,
      confirmText: opt.confirmText || "确定",
      cancelText: "取消",
      success(res) {
        if (res.confirm) {
          sure && sure(res)
        } else {
          opt.cancel && opt.cancel()
        }
      }
    })
  }

  //actionSheet
  actionSheet(itemList, success, cancel) {
    wx.showActionSheet({
      itemList,
      success(res) {
        if (!res.cancel) {
          success && success(res.tapIndex)
        } else {
          cancel && cancel()
        }
      },
      fail() {
        cancel && cancel()
      }
    })
  }

  //getPower
  getPower(uuid, cb) {
    let $fn = (uuid) => {
      if (uuid === '') {
        return false
      }
      this.get("/campus/detail/" + uuid, {}, (data) => {
        wx.setStorageSync('cmp_name', data.name);
        let power = data.user_kind
        if (power == 'admin' || power == 'owner') {
          wx.setStorageSync('$isTeacher', 'no')
        } else {
          wx.setStorageSync('$isTeacher', 'yes')
        }
        cb && cb(data)
      }, null, false, false)
    }
    if (uuid && uuid !== '') {
      $fn(uuid)
    } else {
      this.cmp_uuid((uuid) => {
        $fn(uuid)
      }, false)
    }
  }

  updatePower(uuid, cb) {
    this.getPower(uuid, cb)
  }


  //openLocation
  openLocation(opt) {
    this.setting("scope.userLocation", () => {
      wx.openLocation(opt)
    })
  }

  //chooseImage
  chooseImage(opt) {
    this.self()._$chooseImage = opt.success
    wx.chooseImage({
      count: 1,
      sizeType: "compressed",
      success: (res) => {
        this.navigateTo("/_common/cutInside?src=" + encodeURIComponent(res.tempFilePaths[0]) + "&ratio=" + opt.ratio + "&prefix=" + opt.prefix)
      }
    })
  }
	requestPayment(ord_id, cb, err) {
		wx.showLoading();
		wx.login({
			fail: (res) => {
				console.log(res);
			},
			success: (res) => {
        const accountInfo = wx.getAccountInfoSync();
				this.get(
					"/group/order/pay",
					{
						pay_channel: "NBZN",
						trade_type: "KDAPP",
						code: res.code,
						order_uuid: ord_id,
            icbc_client_type:23,
            zonecode:wx.getStorageSync('addresscode')
					},
					(data) => {
						wx.hideLoading();
						let e = data;
						if (e.pay_channel && e.pay_channel == "SXZPAY") {
							if (cb) {
								cb({});
							} else {
								wx.showToast({
									title: "支付成功!",
								});
							}
						} else {
							wx.requestPayment({
								timeStamp: e.timeStamp.toString(),
								nonceStr: e.nonceStr,
								package: e.package,
								signType: e.signType,
								paySign: e.paySign,
								success: (res) => {
									if (cb) {
										cb(res);
									} else {
										wx.showToast({
											title: "支付成功!",
										});
									}
								},
								fail: (res) => {
                  console.log(res);
									if (err) {
										err(res);
									} else {
										// this.tip("你取消了支付或支付失败!")
										// this.get(
										// 	"/order/" + ord_id + "/close",
										// 	{
										// 		order_uuid: ord_id,
										// 	},
										// 	(e) => {
										// 		this.navigateTo(
										// 			"/course/payresult?type=fail&uuid=" + ord_id,
										// 			1
										// 		);
										// 	}
										// );
									}
								},
							});
						}
					}
				);
			},
		});
	}
  //setWxShare
  setWxShare(e) {
    if (e.wx_share_type == "share" || e.scene) {
      this.self().goHome = () => {
        wx.switchTab({
          url: "/pages/index/index"
        })
      }
      this.self().setData({
        wx_share_type: "share"
      })
    }
  }
  // 获取用户信息
  getUserInfo(cb, desc = '用于完善用户资料') {
    let userInfo = this.gData().userInfo
    if (userInfo) {
      cb && cb(userInfo)
    } else {
      wx.getUserProfile({
        desc,
        success: (res) => {
          this.gData().userInfo = res
          cb && cb(res)
        },
        fail(err) {
          console.warn(err.errMsg || "")
          wx.showModal({
            content: "微信授权失败",
            showCancel: false,
          });
        }
      })
    }
  }
  // 判断是否为JSON
  isJSON(str) {
    if (typeof str == 'string') {
      try {
        var obj = JSON.parse(str);
        if (typeof obj == 'object' && obj) {
          return true;
        } else {
          return false;
        }

      } catch (e) {
        console.log('error：' + str + '!!!' + e);
        return false;
      }
    }
    console.log('It is not a string!')
  }
  basismedia(InnerAudioContex, recorderManager) {
    let This = this
    let audio = InnerAudioContex
    let recorder = recorderManager
    return {
      data: {
        palyAudio: {},
        show: true,
        audio_names: [],
        audio_durations: [],
      },
      onLoads(e) {
        audio.onPlay(() => {
          console.log('开始播放')
        })
        audio.onStop(() => {
          console.log('停止播放')
        })
        audio.onEnded(() => {
          console.log('播放结束')
          for (let i in this.data.palyAudio) {
            this.data.palyAudio[i] = false
          }
          This.self().setData({
            palyAudio: this.data.palyAudio
          })
        })
        audio.onError((res) => {
          console.log(res.errMsg)
          console.log(res.errCode)
        })
      },
      start(countdown) {
        const options = {
          duration: 600000, //指定录音的时长，单位 ms
          sampleRate: 16000, //采样率
          numberOfChannels: 1, //录音通道数
          encodeBitRate: 96000, //编码码率
          format: 'mp3', //音频格式，有效值 aac/mp3
          frameSize: 50, //指定帧大小，单位 KB
        }
        //开始录音
        recorder.start(options);
        recorder.onStart(() => {
          console.log('recorder start')
          let _fn = () => {
            This.self().setData({
              countdown: countdown,
            })
            countdown--
          }
          _fn()
          this.setTimeDentify = setInterval(() => {
            _fn()
          }, 1000)
          This.self().setData({
            show: false
          })
        });
        recorder.onError((res) => {
          console.log(res);
        })
      },
      closeMask() {
        clearInterval(this.setTimeDentify)
        This.self().setData({
          flag: true,
          countdown: 600,
          show: true
        })
      },
      //播放声音
      playVoice(e) {
        audio.stop()
        // audio.src = This.data(e).item.audio_url_temp || This.data(e).item.audio_url
        let audio_url = This.data(e).item.audio_url
        if (audio_url.indexOf(':') === -1) {
          audio_url = "https://sxzaudio.oss-cn-shanghai.aliyuncs.com/" + audio_url;
        }
        audio.src = audio_url
        let cAudioIndex = This.data(e).index
        for (let i in this.data.palyAudio) {
          if (i != cAudioIndex) {
            this.data.palyAudio[i] = false
          }
        }
        if (!this.data.palyAudio[cAudioIndex]) {
          audio.play()
          this.data.palyAudio[cAudioIndex] = true
        } else {
          audio.stop()
          this.data.palyAudio[cAudioIndex] = false
        }
        This.self().setData({
          palyAudio: this.data.palyAudio
        })
      },
      // 播放视频
      playVideo(e) {
        This.self().setData({
          video_urls_s: This.data(e).item.video_url_temp || This.data(e).item.video_url,
          palyAudio: this.data.palyAudio
        })
        var videoContext = wx.createVideoContext('indexVideo', this);
        videoContext.requestFullScreen();
        videoContext.play()
      },
      closeVideo() {
        var videoContext = wx.createVideoContext('indexVideo', this);
        videoContext.exitFullScreen();
      },
      fullScreen(e) {
        var isFull = e.detail.fullScreen;
        This.self().setData({
          fullScreen: isFull
        })
      },
      // 停止播放声音
      stopPlay() {
        audio.stop()
        for (let i in this.data.palyAudio) {
          this.data.palyAudio[i] = false
        }
      },
      // 看大图
      pImg(e) {
        let src = This.data(e).item
        wx.previewImage({
          current: src,
          urls: [src]
        })
      },
      // 删除录音
      delvoice(s, e) {
        s.audio_urls.splice(This.data(e).index, 1)
        s.audio_durations.splice(This.data(e).index, 1)
        s.audio_names.splice(This.data(e).index, 1)
        This.self().setData({
          audio_urls: s.audio_urls,
        })
      },
      delvideo(s, e) {
        s.video_urls.splice(This.data(e).index, 1)
        s.video_covers.splice(This.data(e).index, 1)
        s.video_names.splice(This.data(e).index, 1)
        This.self().setData({
          video_urls: s.video_urls,
        })
      },
      delimg(s, e) {
        s.splice(This.data(e).index, 1)
        This.self().setData({
          img_urls: s
        })
      },
      onUnload() {
        audio.stop()
        This.self().setData({
          palyAudio: {}
        })
      }
    }
  }

  //课堂点评是否开通
  authority(callback) {
    this.get('/campus/authority', {
      "func_id": "HOMEWORK"
    }, res => {
      if (res.status) {
        callback && callback();
      } else {
        this.confirm('当前校区未开通学员点评功能请联系客服了解详情', () => {
          wx.makePhoneCall({
            phoneNumber: '4007661816',
          })
        }, {
          confirmText: '联系客服'
        })
      }
    })
  }

  //检测视频转码状态
  videoTransStatus(url, cb) {
    if (url.indexOf("://") === -1) {
      url = "https://sxzvideo.oss-cn-shanghai.aliyuncs.com/" + url;
    }
    this.get("/video/exists", {
      media_path: url,
    }, (res) => {
      if (res.exists === "YES") {
        cb(url)
      } else {
        wx.hideLoading();
        this.alert("抱歉，当前视频还在转码中，请稍后重试！");
      }
    });
  }

  //_components_modal
  modal_init() {
    this.self().setData({
      _components_modal_hide: true
    })
    this.self()._components_modal_close = () => {
      this.self().setData({
        _components_modal_hide: true
      })
    }
    this.self()._components_modal_open = () => {
      this.self().setData({
        _components_modal_hide: false
      })
    }
  }
  //components init
  components(names) {
    names.forEach((name) => {
      this[name + "_init"]();
    })
  }

}

export default new $()